package com.wzz.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzz.config.FreemarkerUtil;
import com.wzz.mapper.FormatMapper;
import com.wzz.mapper.ProductMapper;
import com.wzz.pojo.Format;
import com.wzz.pojo.Product;
import com.wzz.pojo.vo.MessageVo;
import com.wzz.pojo.vo.PageInfoVo;
import com.wzz.pojo.vo.R;
import com.wzz.service.ProductService;
import freemarker.template.TemplateException;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @author DarkClown
 * @date 2024-08-05 09:34
 * @project_name day0805-week3
 * @parem
 **/
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper,Product> implements ProductService {
    @Autowired
    ProductMapper productMapper;

    @Autowired
    FormatMapper formatMapper;

    @Autowired
    HttpServletRequest httpServletRequest;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;



    @Override
    public R selectList(PageInfoVo pageInfoVo) {

        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();

        if (!StringUtils.isEmpty(pageInfoVo.getKeyWord())){
            //名称模糊查询
            queryWrapper.lambda().like(Product::getPname,pageInfoVo.getKeyWord());

        }
        if (!StringUtils.isEmpty(pageInfoVo.getLot())){
            //名称模糊查询
            queryWrapper.lambda().like(Product::getLot,pageInfoVo.getLot());

        }
            //时间区间查询
        if (!StringUtils.isEmpty(pageInfoVo.getBeginTime())&&!StringUtils.isEmpty(pageInfoVo.getEndTime())){
            queryWrapper.lambda().le(Product::getCreatTime,pageInfoVo.getEndTime()).ge(Product::getCreatTime,pageInfoVo.getBeginTime());
        }

        queryWrapper.lambda().orderByDesc(Product::getPid);

        Page<Product> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());

        Page<Product> selectPage = productMapper.selectPage(page, queryWrapper);

        HashMap<String, Object> map = new HashMap<>();
        map.put("pageSize",pageInfoVo.getPageSize());
        map.put("pageNum",pageInfoVo.getPageNum());
        map.put("records",selectPage.getRecords());
        map.put("total",selectPage.getRecords().size());

        return R.OK(map);
    }

    @Override
    public R selectFormat() {
        List<Format> formatList = formatMapper.selectList(null);

        return R.OK(formatList);
    }
    @PostConstruct
    private void innit(){
        //不丢失
        rabbitTemplate.setReturnCallback(
                new RabbitTemplate.ReturnCallback() {
                    @Override
                    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                        rabbitTemplate.convertAndSend(exchange,routingKey,message);
                    }
                }
        );
        rabbitTemplate.setConfirmCallback(
                new RabbitTemplate.ConfirmCallback() {
                    @Override
                    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                        if (ack){
                            System.out.println("发送成功");
                        }else {
                            System.out.println("发送失败");
                        }
                    }
                }
        );

    }

    @Override
    public R insertProduct(Product product) {
        product.setCreatTime(new Date());
        Integer num = product.getNum();
        String code = "";
        if (product.getFname().equals("前缀+字母和数字")){
            code = "qg"+ RandomUtil.randomString(num-2);
        }
        if (product.getFname().equals("前缀+字母（不限大小写）")){
            code = "qg"+ RandomStringUtils.randomAlphabetic(num-2);
        }
        if (product.getFname().equals("前缀+数字")){
            code = "qg"+ RandomUtil.randomNumbers(num-2);
        }
        if (product.getFname().equals("前缀+字母（大写）")){
            code = "qg"+ RandomStringUtils.randomAlphabetic(num-2).toUpperCase();
        }

        product.setSecurity(code);

        productMapper.insert(product);
        //获取ip+id当做唯一键
        String ip = httpServletRequest.getRemoteAddr().toString();
        MessageVo messageVo = new MessageVo();
        messageVo.setMsgId(ip+product.getPid());
        messageVo.setMsgBody(JSON.toJSONString(product));
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        //重复发送
        if (stringRedisTemplate.hasKey(messageVo.getMsgId())){
            return R.ERROR(404,"不能重复发送");
        }

        opsForValue.set(messageVo.getMsgId(),messageVo.getMsgBody());

        String s = opsForValue.get(ip + product.getPid() + "num");

        Integer showNum = 0;

        if (StringUtils.isEmpty(s)){
            showNum = 0;
        }else {
            showNum = Integer.valueOf(s);
        }
        opsForValue.set(messageVo.getMsgId()+"num", String.valueOf(showNum+1));
        //发送
        rabbitTemplate.convertAndSend("addExchange","",JSON.toJSONString(messageVo));
        //删除缓存
        stringRedisTemplate.delete(messageVo.getMsgId());

        return R.OK();
    }

    @Override
    public R selectPro(Integer id) {
        Product product = productMapper.selectById(id);
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        String ip = httpServletRequest.getRemoteAddr().toString();
        String s = opsForValue.get(ip + id + "num");

        Integer showNum = 0;

        if (StringUtils.isEmpty(s)){
            showNum = 0;
        }else {
            showNum = Integer.valueOf(s);
        }

        HashMap<String, Object> map = new HashMap<>();

        map.put("pro",product);
        map.put("num",showNum);
        opsForValue.set(ip+id+"num", String.valueOf(++showNum));


        //创建页面
        FreemarkerUtil freemarkerUtil = new FreemarkerUtil();
        String path = "C:\\Users\\Administrator\\Desktop\\Freemaker\\"+ UUID.randomUUID().toString()+".html";
        try {
            freemarkerUtil.createHtml(map,"template",path);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TemplateException e) {
            throw new RuntimeException(e);
        }

        return R.OK();

    }


    //消费1
    @RabbitListener(queues = "addQueue1")
    public void addQueue1(Message message, Channel channel){

        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();



        String body = new String(message.getBody());
//        Product product1 = JSON.parseObject(body, Product.class);
        MessageVo messageVo = JSON.parseObject(body, MessageVo.class);
        HashMap<String, Object> map = new HashMap<>();
        //显示次数
        String showNum = opsForValue.get(messageVo.getMsgId() + "num");
        Product product = JSON.parseObject(messageVo.getMsgBody(), Product.class);

        map.put("pro",product);
        map.put("num",showNum);
        //创建页面
        FreemarkerUtil freemarkerUtil = new FreemarkerUtil();
        String path = "C:\\Users\\Administrator\\Desktop\\Freemaker\\"+ UUID.randomUUID().toString()+".html";
        try {
            freemarkerUtil.createHtml(map,"template",path);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TemplateException e) {
            throw new RuntimeException(e);
        }
    }
    //消费2
    @RabbitListener(queues = "addQueue2")
    public void addQueue2(Message message, Channel channel)  {

        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();



        String body = new String(message.getBody());
        MessageVo messageVo = JSON.parseObject(body, MessageVo.class);
        HashMap<String, Object> map = new HashMap<>();
        //显示次数
        String showNum = opsForValue.get(messageVo.getMsgId() + "num");
        Product product = JSON.parseObject(messageVo.getMsgBody(), Product.class);

        map.put("pro",product);
        map.put("num",showNum);
        //创建页面
        FreemarkerUtil freemarkerUtil = new FreemarkerUtil();
        String path = "C:\\Users\\Administrator\\Desktop\\Freemaker\\"+ UUID.randomUUID().toString()+".html";
        try {
            freemarkerUtil.createHtml(map,"template",path);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TemplateException e) {
            throw new RuntimeException(e);
        }

    }

}
